package com.gnomon.epsos.service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.Vector;

import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.portlet.PortletRequest;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import org.apache.log4j.Priority;
import org.opensaml.Configuration;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.SAMLObjectBuilder;
import org.opensaml.common.SAMLVersion;
import org.opensaml.common.SignableSAMLObject;
import org.opensaml.saml2.core.Advice;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.AssertionIDRef;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.AttributeValue;
import org.opensaml.saml2.core.AuthnContext;
import org.opensaml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml2.core.AuthnStatement;
import org.opensaml.saml2.core.Conditions;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.Subject;
import org.opensaml.saml2.core.SubjectConfirmation;
import org.opensaml.saml2.core.impl.AssertionMarshaller;
import org.opensaml.saml2.core.impl.IssuerBuilder;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.XMLObjectBuilder;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.io.MarshallingException;
import org.opensaml.xml.schema.XSString;
import org.opensaml.xml.schema.XSURI;
import org.opensaml.xml.security.SecurityConfiguration;
import org.opensaml.xml.security.SecurityHelper;
import org.opensaml.xml.security.credential.Credential;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.gnomon.LiferayUtils;
import com.gnomon.epsos.model.*;
import com.gnomon.epsos.model.cda.CDAHeader;
import com.gnomon.epsos.model.cda.CDAUtils;
import com.gnomon.epsos.model.cda.EDDetail;
import com.gnomon.epsos.model.cda.PersonDetail;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.model.Company;
import com.liferay.portal.model.User;
import com.liferay.portal.service.CompanyLocalServiceUtil;
import com.liferay.portal.service.RoleServiceUtil;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portal.util.PortalUtil;
import com.liferay.util.portlet.PortletProps;

import epsos.ccd.gnomon.configmanager.ConfigurationManager;
import epsos.ccd.gnomon.configmanager.ConfigurationManagerService;
import epsos.ccd.gnomon.xslt.EpsosXSLTransformer;
import epsos.ccd.netsmart.securitymanager.key.KeyStoreManager;
import epsos.ccd.netsmart.securitymanager.key.impl.DefaultKeyStoreManager;
import epsos.ccd.netsmart.securitymanager.sts.client.TRCAssertionRequest;
import epsos.openncp.protocolterminator.ClientConnectorConsumer;
import epsos.openncp.protocolterminator.clientconnector.EpsosDocument1;
import epsos.openncp.protocolterminator.clientconnector.GenericDocumentCode;
import epsos.openncp.protocolterminator.clientconnector.PatientId;
import eu.epsos.util.xca.XCAConstants.EXTRINSIC_OBJECT.FormatCode;

public class EpsosHelperService {

	private static Logger log = Logger.getLogger("EpsosHelperService");
	private static Base64 decode = new Base64();
	public final static SimpleDateFormat dateMetaDataFormat = new SimpleDateFormat(
			"yyyyMMdd");
	

	public EpsosHelperService() {
		super();
		// TODO Auto-generated constructor stub
	}

	public void sayHello() {
		// _log.error("");
	}

//	public void writeDispensationDocument(byte[] bytes, Assertion hcp,
//			Assertion trca, byte[] bytesDispPdf, Patient patient,
//			String country, User user, String language, String fullname) {
//		log.info("Starting the preparation of the eD doc ....");
//
//		String serviceUrl = com.liferay.util.portlet.PortletProps
//				.get("client.connector.service.url");
//		ClientConnectorConsumer clientConectorConsumer = new ClientConnectorConsumer(
//				serviceUrl);
//
//		GenericDocumentCode classCode = GenericDocumentCode.Factory
//				.newInstance();
//		classCode.setNodeRepresentation(PortletProps
//				.get("dispensation.classCode"));
//		classCode.setSchema(PortletProps.get("classcode.schema"));
//		classCode.setValue(PortletProps.get("dispensation.value"));
//
//		GenericDocumentCode formatCode = GenericDocumentCode.Factory
//				.newInstance();
//
//		formatCode.setSchema(PortletProps
//				.get("dispensation.formatcode.codingschema"));
//		formatCode.setNodeRepresentation(PortletProps
//				.get("dispensation.formatcode.noderepresentation"));
//		formatCode.setValue(PortletProps
//				.get("dispensation.formatcode.displayname"));
//
//		EpsosDocument1 document = EpsosDocument1.Factory.newInstance();
//		document.setAuthor(user.getFullName());
//		Calendar cal = Calendar.getInstance();
//		document.setCreationDate(cal);
//		document.setDescription("eDispensation");
//		document.setTitle("eDispensation");
//		document.setUuid(UUID.randomUUID() + "");
//		document.setClassCode(classCode);
//		document.setFormatCode(formatCode);
//		document.setBase64Binary(bytes);
//		// document.setFormatCode(aux.getFormatCode());
//		// document.setRepositoryId(aux.getRepositoryId());
//		// document.setHcid(aux.getHcid());
//
//		 clientConectorConsumer.submitDocument(hcp, trca, country,
//		 document,patient);
//		 try
//		 {
//		 String fc_nr = GetterUtil.getString(PortletProps.get("ed.code"), "60593-1");
//		 String fc_cs = GetterUtil.getString(PortletProps.get("ed.coding.scheme"), "epSOS formatCodes");
//		 fc_cs="epSOS formatCodes";
//		 String fc_v = GetterUtil.getString(GnPropsUtil.get("portalb","ed.epsos.coding.scheme"), "urn:epSOS:ep:dis:2010");
//		 String fc_v1 = "urn:uuid:a09d5840-386c-46f2-b5ad-9c3699a4309d";
//
//		// subm.getDocuments().add(doc);
//		// log.info("UPLOAD DISP DOC REQUEST:" +patientName,usr);
//		// boolean submitDispDocument =
//		// GetterUtil.getBoolean(GnPropsUtil.get("portalb",
//		// "epsos.submit.disp.document"), true);
//		//
//		// byte[] docbytes = subm.getDocuments().get(0).getBytes();
//		// String edcda = new String(docbytes);
//		// if (submitDispDocument)
//		// {
//		// webservice.submitDocument(subm, patient);
//		// log.info("The eD doc will be submitted");
//		// }
//		// else
//		// {
//		// log.info("The eD doc will NOT be submitted");
//		// }
//		log.info("UPLOAD DISP DOC RESPONSE OK:" + patient.getName());
//	}

	private static PersonDetail getPharmacistInfo(User user) {

		PersonDetail pd = new PersonDetail();
		pd.setFirstname(user.getFirstName());
		pd.setLastname(user.getLastName());
		pd.setOrgname(user.getLastName() + " " + user.getFirstName());
		pd.setEmail(user.getEmailAddress());
		pd.setOrgid(user.getUserId() + "");
		Company company;
		try {
			company = CompanyLocalServiceUtil.getCompanyById(user
					.getCompanyId());
			pd.setCountry(company.getLocale().getCountry());
		} catch (PortalException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SystemException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// pd.setPostalCode(addressLang.getZipOrPostCode());
		// pd.setAddress(addressLang.getAddressLine());
		// pd.setCity(addressLang.getRegion());
		return pd;
	}

	// public static ByteArrayOutputStream ConvertHTMLtoPDF(String htmlin,
	// String uri)
	// {
	// ByteArrayOutputStream out = new ByteArrayOutputStream();
	// CYaHPConverter converter = new CYaHPConverter();
	//
	// try
	// {
	// List headerFooterList = new ArrayList();
	// System.out.println("before conversion");
	// Map properties = new HashMap();
	// headerFooterList.add(new IHtmlToPdfTransformer.CHeaderFooter(
	// "<table width=\"100%\"><tbody><tr><td align=\"left\">Generated with Gi9 Portal.</td><td align=\"right\">Page <pagenumber>/<pagecount></td></tr></tbody></table>",
	// IHtmlToPdfTransformer.CHeaderFooter.HEADER));
	// headerFooterList.add(new IHtmlToPdfTransformer.CHeaderFooter(
	// "Ξ’Β© 2011 Produced by Gnomon Portal Solution",
	// IHtmlToPdfTransformer.CHeaderFooter.FOOTER));
	//
	// properties.put(IHtmlToPdfTransformer.PDF_RENDERER_CLASS,
	// IHtmlToPdfTransformer.FLYINGSAUCER_PDF_RENDERER);
	// converter.convertToPdf(htmlin,
	// IHtmlToPdfTransformer.A4P, headerFooterList, uri, out,
	// properties);
	// System.out.println("after conversion");
	// out.flush();
	// out.close();
	// } catch (Exception e)
	// {
	// _log.error("Error converting html to pdf");
	// e.printStackTrace();
	// }
	// return out;
	// }

	public void uploadDispensationDocument(byte[] bytes, Assertion hcp,
			Assertion trca, Patient patient, String country, User usr,
			String language, String fullname) {
		// String xmlfile = "";
		// String transformedResult="";
		// try
		// {
		// xmlfile = new String(bytes,"UTF-8");
		//
		// EpsosXSLTransformer xlsClass= new EpsosXSLTransformer();
		// String lang1 = language.replace("_","-");
		// transformedResult= xlsClass.transform(xmlfile,lang1,"");
		// }
		// catch (Exception e)
		// {
		// log.error("Error transforming xml to html");
		// }
		//
		// ByteArrayOutputStream bos = null;
		// // try
		// // {
		// // bos =
		// EpsosHelperService.getInstance().ConvertHTMLtoPDF(transformedResult,
		// epsosWebServiceURL);
		// // }
		// // catch (Exception e)
		// // {
		// // _log.error("ERROR creating pdf version of ed");
		// // }
		//
		// writeDispensationDocument(bytes,hcp, trca,patient,
		// country, usr,language,fullname);
	}

	public static byte[] generateDispensationDocumentFromPrescription2(
			byte[] bytes, List<ViewResult> lines,
			List<ViewResult> dispensedLines, User user) {

		byte[] bytesED = null;

		PersonDetail pd = getPharmacistInfo(user);

		String edDoc = "";
		CDAHeader cda = new CDAHeader();
		Date now = new Date();
		cda.setEffectiveTime(EpsosHelperService.formatDateHL7(now));
		cda.setLanguageCode(user.getLanguageId());
		cda.setPharmacistAddress(pd.getAddress());
		cda.setPharmacistCity(pd.getCity());
		cda.setPharmacistPostalCode(pd.getPostalCode());
		cda.setPharmacistCountry(pd.getCountry());
		cda.setPharmacistTelephone("N/A");
		cda.setPharmacistEmail(pd.getEmail());
		cda.setPharmacistFamilyName(pd.getLastname());
		cda.setPharmacistGivenName(pd.getFirstname());
		cda.setPharmacistOrgId(pd.getOrgid());
		cda.setPharmacistOrgName(pd.getOrgname());
		cda.setPharmacistOrgAddress("N/A");
		cda.setPharmacistOrgCity("N/A");
		cda.setPharmacistOrgPostalCode("N/A");
		cda.setPharmacistOrgCountry(pd.getCountry());

		List<EDDetail> edDetails = new ArrayList();
		for (int i = 0; i < dispensedLines.size(); i++) {
			ViewResult d_line = (ViewResult) dispensedLines.get(i);
			EDDetail ed = new EDDetail();
			ed.setRelativePrescriptionLineId(d_line.getField1().toString());
			ed.setDispensedQuantity(d_line.getField7().toString());
			ed.setMedicineFormCode(d_line.getField5().toString());
			ed.setMedicineCommercialName(d_line.getField2().toString());
			edDetails.add(ed);
		}
		cda.setEDDetail(edDetails);
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document epDoc = db.parse(new ByteArrayInputStream(bytes));
			cda.setPrescriptionBarcode(CDAUtils
					.getRelativePrescriptionBarcode(epDoc));
			cda.setDispensationId("D-"
					+ CDAUtils.getRelativePrescriptionBarcode(epDoc));
			edDoc = CDAUtils.createDispensation(epDoc, cda);
			log.info(edDoc);
		} catch (Exception e) {
			log.error("error creating disp doc");
		}
		return edDoc.getBytes();
	}

	public static List<ViewResult> parsePrescriptionDocumentForPrescriptionLines(
			byte[] bytes) {
		ArrayList<ViewResult> lines = new ArrayList<ViewResult>();
		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document dom = db.parse(new ByteArrayInputStream(bytes));

			XPath xpath = XPathFactory.newInstance().newXPath();

			XPathExpression performerPrefixExpr = xpath
					.compile("/ClinicalDocument/author/assignedAuthor/assignedPerson/name/prefix");
			XPathExpression performerSurnameExpr = xpath
					.compile("/ClinicalDocument/author/assignedAuthor/assignedPerson/name/family");
			XPathExpression performerGivenNameExpr = xpath
					.compile("/ClinicalDocument/author/assignedAuthor/assignedPerson/name/given");
			XPathExpression professionExpr = xpath
					.compile("/ClinicalDocument/author/functionCode");
			XPathExpression facilityNameExpr = xpath
					.compile("/ClinicalDocument/author/assignedAuthor/representedOrganization/name");
			XPathExpression facilityAddressStreetExpr = xpath
					.compile("/ClinicalDocument/author/assignedAuthor/representedOrganization/addr/streetAddressLine");
			XPathExpression facilityAddressZipExpr = xpath
					.compile("/ClinicalDocument/author/assignedAuthor/representedOrganization/addr/postalCode");
			XPathExpression facilityAddressCityExpr = xpath
					.compile("/ClinicalDocument/author/assignedAuthor/representedOrganization/addr/city");
			XPathExpression facilityAddressCountryExpr = xpath
					.compile("/ClinicalDocument/author/assignedAuthor/representedOrganization/addr/country");
			XPathExpression prescriptionIDExpr = xpath
					.compile("/ClinicalDocument/component/structuredBody/component/section[templateId/@root='1.3.6.1.4.1.12559.11.10.1.3.1.2.1']");

			String performer = "";
			Node performerPrefix = (Node) performerPrefixExpr.evaluate(dom,
					XPathConstants.NODE);
			if (performerPrefix != null) {
				performer += performerPrefix.getTextContent().trim() + " ";
			}
			Node performerSurname = (Node) performerSurnameExpr.evaluate(dom,
					XPathConstants.NODE);
			if (performerSurname != null) {
				performer += performerSurname.getTextContent().trim();
			}
			Node performerGivenName = (Node) performerGivenNameExpr.evaluate(
					dom, XPathConstants.NODE);
			if (performerGivenName != null) {
				performer += " " + performerGivenName.getTextContent().trim();
			}

			String profession = "";
			Node professionNode = (Node) professionExpr.evaluate(dom,
					XPathConstants.NODE);
			if (professionNode != null) {
				profession += professionNode.getAttributes()
						.getNamedItem("displayName").getNodeValue();
			}

			String facility = "";
			Node facilityNode = (Node) facilityNameExpr.evaluate(dom,
					XPathConstants.NODE);
			if (facilityNode != null) {
				facility += facilityNode.getTextContent().trim();
			}

			String address = "";
			Node street = (Node) facilityAddressStreetExpr.evaluate(dom,
					XPathConstants.NODE);
			if (street != null) {
				address += street.getTextContent().trim();
			}
			Node zip = (Node) facilityAddressZipExpr.evaluate(dom,
					XPathConstants.NODE);
			if (zip != null) {
				address += ", " + zip.getTextContent().trim();
			}
			Node city = (Node) facilityAddressCityExpr.evaluate(dom,
					XPathConstants.NODE);
			if (city != null) {
				address += ", " + city.getTextContent().trim();
			}
			Node country = (Node) facilityAddressCountryExpr.evaluate(dom,
					XPathConstants.NODE);
			if (country != null) {
				address += ", " + country.getTextContent().trim();
			}

			// for each prescription component, search for its entries and make
			// up the list
			String prescriptionID = "";
			NodeList prescriptionIDNodes = (NodeList) prescriptionIDExpr
					.evaluate(dom, XPathConstants.NODESET);
			if (prescriptionIDNodes != null
					&& prescriptionIDNodes.getLength() > 0) {
				XPathExpression idExpr = xpath.compile("id");
				XPathExpression entryExpr = xpath
						.compile("entry/substanceAdministration");
				XPathExpression nameExpr = xpath
						.compile("consumable/manufacturedProduct/manufacturedMaterial/name");

				XPathExpression freqExpr = xpath
						.compile("effectiveTime[@type='PIVL_TS']/period");
				XPathExpression doseExpr = xpath.compile("doseQuantity");
				XPathExpression doseExprLow = xpath.compile("low");
				XPathExpression doseExprHigh = xpath.compile("high");
				XPathExpression doseFormExpr = xpath
						.compile("consumable/manufacturedProduct/manufacturedMaterial/formCode");
				XPathExpression packQuantityExpr = xpath
						.compile("consumable/manufacturedProduct/manufacturedMaterial/asContent/quantity/numerator[@type='epsos:PQ']");
				XPathExpression packQuantityExpr2 = xpath
						.compile("consumable/manufacturedProduct/manufacturedMaterial/asContent/quantity/denominator[@type='epsos:PQ']");
				XPathExpression packTypeExpr = xpath
						.compile("consumable/manufacturedProduct/manufacturedMaterial/asContent/containerPackagedMedicine/formCode");

				XPathExpression packageExpr = xpath
						.compile("consumable/manufacturedProduct/manufacturedMaterial/asContent/containerPackagedMedicine/capacityQuantity");

				XPathExpression ingredientExpr = xpath
						.compile("consumable/manufacturedProduct/manufacturedMaterial/ingredient[@classCode='ACTI']/ingredient/code");
				XPathExpression strengthExpr = xpath
						.compile("consumable/manufacturedProduct/manufacturedMaterial/ingredient[@classCode='ACTI']/quantity/numerator[@type='epsos:PQ']");
				XPathExpression strengthExpr2 = xpath
						.compile("consumable/manufacturedProduct/manufacturedMaterial/ingredient[@classCode='ACTI']/quantity/denominator[@type='epsos:PQ']");

				XPathExpression nrOfPacksExpr = xpath
						.compile("entryRelationship/supply/quantity");
				// XPathExpression nrOfPacksExpr =
				// xpath.compile("consumable/manufacturedProduct/manufacturedMaterial/asContent/quantity/denominator[@type='epsos:PQ']");

				XPathExpression routeExpr = xpath.compile("routeCode");
				XPathExpression lowExpr = xpath
						.compile("effectiveTime[@type='IVL_TS']/low");
				XPathExpression highExpr = xpath
						.compile("effectiveTime[@type='IVL_TS']/high");
				XPathExpression patientInstrEexpr = xpath
						.compile("entryRelationship/act/code[@code='PINSTRUCT']/../text/reference[@value]");
				XPathExpression fillerInstrEexpr = xpath
						.compile("entryRelationship/act/code[@code='FINSTRUCT']/../text/reference[@value]");
				XPathExpression substituteInstrExpr = xpath
						.compile("entryRelationship[@typeCode='SUBJ'][@inversionInd='true']/observation[@classCode='OBS']/value");

				XPathExpression prescriberPrefixExpr = xpath
						.compile("author/assignedAuthor/assignedPerson/name/prefix");
				XPathExpression prescriberSurnameExpr = xpath
						.compile("author/assignedAuthor/assignedPerson/name/family");
				XPathExpression prescriberGivenNameExpr = xpath
						.compile("author/assignedAuthor/assignedPerson/name/given");

				for (int p = 0; p < prescriptionIDNodes.getLength(); p++) {
					Node sectionNode = prescriptionIDNodes.item(p);
					Node pIDNode = (Node) idExpr.evaluate(sectionNode,
							XPathConstants.NODE);
					if (pIDNode != null)
						try {
							prescriptionID = pIDNode.getAttributes()
									.getNamedItem("extension").getNodeValue();
							// prescriptionID =
							// pIDNode.getAttributes().getNamedItem("root").getNodeValue();
						} catch (Exception e) {

						}
					else
						prescriptionID = "";

					String prescriber = "";
					Node prescriberPrefix = (Node) prescriberPrefixExpr
							.evaluate(sectionNode, XPathConstants.NODE);
					if (prescriberPrefix != null) {
						prescriber += prescriberPrefix.getTextContent().trim()
								+ " ";
					}
					Node prescriberSurname = (Node) prescriberSurnameExpr
							.evaluate(sectionNode, XPathConstants.NODE);
					if (prescriberSurname != null) {
						prescriber += prescriberSurname.getTextContent().trim();
					}
					Node prescriberGivenName = (Node) prescriberGivenNameExpr
							.evaluate(sectionNode, XPathConstants.NODE);
					if (prescriberGivenName != null) {
						prescriber += " "
								+ prescriberGivenName.getTextContent().trim();
					}

					if (Validator.isNull(prescriber))
						prescriber = performer;

					// PRESCRIPTION ITEMS
					NodeList entryList = (NodeList) entryExpr.evaluate(
							sectionNode, XPathConstants.NODESET);
					if (entryList != null && entryList.getLength() > 0) {
						for (int i = 0; i < entryList.getLength(); i++) {
							ViewResult line = new ViewResult(i);

							Node entryNode = entryList.item(i);

							String materialID = "";
							Node materialIDNode = (Node) idExpr.evaluate(
									entryNode, XPathConstants.NODE);
							if (materialIDNode != null) {
								try {
									materialID = materialIDNode.getAttributes()
											.getNamedItem("extension")
											.getNodeValue();
								} catch (Exception e) {
									System.out
											.println("Error getting material");
								}
							}

							Node materialName = (Node) nameExpr.evaluate(
									entryNode, XPathConstants.NODE);
							String name = materialName.getTextContent().trim();

							String packsString = "";
							Node doseForm = (Node) doseFormExpr.evaluate(
									entryNode, XPathConstants.NODE);
							if (doseForm != null)
								packsString = doseForm.getAttributes()
										.getNamedItem("displayName")
										.getNodeValue();

							Node packageExpr1 = (Node) packageExpr.evaluate(
									entryNode, XPathConstants.NODE);
							Node packType = (Node) packTypeExpr.evaluate(
									entryNode, XPathConstants.NODE);
							Node packQuant = (Node) packQuantityExpr.evaluate(
									entryNode, XPathConstants.NODE);
							Node packQuant2 = (Node) packQuantityExpr2
									.evaluate(entryNode, XPathConstants.NODE);

							String dispensedPackage = "";
							String dispensedPackageUnit = "";
							if (packageExpr1 != null) {
								dispensedPackage = packageExpr1.getAttributes()
										.getNamedItem("value").getNodeValue();
								dispensedPackageUnit = packageExpr1
										.getAttributes().getNamedItem("unit")
										.getNodeValue();
							}
							if (packQuant != null && packType != null
									&& packQuant2 != null) {
								packsString += "#"
										+ packType.getAttributes()
												.getNamedItem("displayName")
												.getNodeValue()
										+ "#"
										+ packQuant.getAttributes()
												.getNamedItem("value")
												.getNodeValue();
								String unit = packQuant.getAttributes()
										.getNamedItem("unit").getNodeValue();
								if (unit != null && !unit.equals("1"))
									packsString += " " + unit;
								String denom = packQuant2.getAttributes()
										.getNamedItem("value").getNodeValue();
								if (denom != null && !denom.equals("1")) {
									packsString += " / " + denom;
									unit = packQuant2.getAttributes()
											.getNamedItem("unit")
											.getNodeValue();
									if (unit != null && !unit.equals("1"))
										packsString += " " + unit;
								}

							}

							String ingredient = "";
							Node ingrNode = (Node) ingredientExpr.evaluate(
									entryNode, XPathConstants.NODE);
							if (ingrNode != null) {
								ingredient += ingrNode.getAttributes()
										.getNamedItem("code").getNodeValue()
										+ " - "
										+ ingrNode.getAttributes()
												.getNamedItem("displayName")
												.getNodeValue();
							}

							String strength = "";
							Node strengthExprNode = (Node) strengthExpr
									.evaluate(entryNode, XPathConstants.NODE);
							Node strengthExprNode2 = (Node) strengthExpr2
									.evaluate(entryNode, XPathConstants.NODE);
							if (strengthExprNode != null
									&& strengthExprNode2 != null) {
								try {
									strength = strengthExprNode.getAttributes()
											.getNamedItem("value")
											.getNodeValue();
								} catch (Exception e) {
									log.error("Error parsing strength");
									strength = "";
								}
								String unit = "";
								String unit2 = "";
								try {
									unit = strengthExprNode.getAttributes()
											.getNamedItem("unit")
											.getNodeValue();
								} catch (Exception e) {
									log.error("Error parsing unit");
								}
								if (unit != null && !unit.equals("1"))
									strength += " " + unit;
								String denom = "";
								try {
									denom = strengthExprNode2.getAttributes()
											.getNamedItem("value")
											.getNodeValue();
								} catch (Exception e) {
									log.error("Error parsing denom");
								}
								if (denom != null) // && !denom.equals("1"))
								{
									strength += " / " + denom;
									try {
										unit2 = strengthExprNode2
												.getAttributes()
												.getNamedItem("unit")
												.getNodeValue();
									} catch (Exception e) {
										log.error("Error parsing unit 2");
									}
									if (unit2 != null && !unit2.equals("1"))
										strength += " " + unit2;
								}

							}

							String nrOfPacks = "";
							Node nrOfPacksNode = (Node) nrOfPacksExpr.evaluate(
									entryNode, XPathConstants.NODE);
							if (nrOfPacksNode != null) {
								if (nrOfPacksNode.getAttributes().getNamedItem(
										"value") != null)
									nrOfPacks = nrOfPacksNode.getAttributes()
											.getNamedItem("value")
											.getNodeValue();
								if (nrOfPacksNode.getAttributes().getNamedItem(
										"unit") != null) {
									String unit = nrOfPacksNode.getAttributes()
											.getNamedItem("unit")
											.getNodeValue();
									if (unit != null && !unit.equals("1"))
										nrOfPacks += " " + unit;
								}
							}

							String doseString = "";
							Node dose = (Node) doseExpr.evaluate(entryNode,
									XPathConstants.NODE);
							if (dose != null) {
								if (dose.getAttributes().getNamedItem("value") != null) {
									doseString = dose.getAttributes()
											.getNamedItem("value")
											.getNodeValue();
									if (dose.getAttributes().getNamedItem(
											"unit") != null) {
										String unit = dose.getAttributes()
												.getNamedItem("unit")
												.getNodeValue();
										if (unit != null && !unit.equals("1"))
											doseString += " " + unit;
									}
								} else {
									String lowString = "", highString = "";
									Node lowDoseNode = (Node) doseExprLow
											.evaluate(dose, XPathConstants.NODE);
									if (lowDoseNode != null
											&& lowDoseNode.getAttributes()
													.getNamedItem("value") != null) {
										lowString = lowDoseNode.getAttributes()
												.getNamedItem("value")
												.getNodeValue();
										if (lowDoseNode.getAttributes()
												.getNamedItem("unit") != null) {
											String unit = lowDoseNode
													.getAttributes()
													.getNamedItem("unit")
													.getNodeValue();
											if (unit != null
													&& !unit.equals("1"))
												lowString += " " + unit;
										}
									}
									Node highDoseNode = (Node) doseExprHigh
											.evaluate(dose, XPathConstants.NODE);
									if (highDoseNode != null
											&& highDoseNode.getAttributes()
													.getNamedItem("value") != null) {
										highString = highDoseNode
												.getAttributes()
												.getNamedItem("value")
												.getNodeValue();
										if (highDoseNode.getAttributes()
												.getNamedItem("unit") != null) {
											String unit = highDoseNode
													.getAttributes()
													.getNamedItem("unit")
													.getNodeValue();
											if (unit != null
													&& !unit.equals("1"))
												highString += " " + unit;
										}
									}

									doseString = Validator.isNotNull(lowString) ? lowString
											: "";
									if (Validator.isNotNull(highString)
											&& !lowString.equals(highString)) {
										doseString = Validator
												.isNotNull(doseString) ? doseString
												+ " - " + highString
												: highString;
									}
								}
							}

							String freqString = "";
							Node period = (Node) freqExpr.evaluate(entryNode,
									XPathConstants.NODE);
							if (period != null) {
								try {
									freqString = getSafeString(period
											.getAttributes()
											.getNamedItem("value")
											.getNodeValue()
											+ period.getAttributes()
													.getNamedItem("unit")
													.getNodeValue());
								} catch (Exception e) {
									log.error("### Error getting freqstring");
								}
							}

							String routeString = "";
							Node route = (Node) routeExpr.evaluate(entryNode,
									XPathConstants.NODE);
							if (route != null)
								try {
									routeString = getSafeString(route
											.getAttributes()
											.getNamedItem("displayName")
											.getNodeValue());
								} catch (Exception e) {
									log.error("error getting route string");
								}

							String patientString = "";
							Node patientInfo = (Node) patientInstrEexpr
									.evaluate(entryNode, XPathConstants.NODE);
							if (patientInfo != null)
								try {
									patientString = getSafeString(patientInfo
											.getAttributes()
											.getNamedItem("value")
											.getNodeValue());
								} catch (Exception e) {
									log.error("error getting route string");
								}

							String fillerString = "";
							Node fillerInfo = (Node) fillerInstrEexpr.evaluate(
									entryNode, XPathConstants.NODE);
							if (fillerInfo != null)
								try {
									fillerString = getSafeString(fillerInfo
											.getAttributes()
											.getNamedItem("value")
											.getNodeValue());
								} catch (Exception e) {
									log.error("error getting route string");
								}

							String lowString = "";
							Node lowNode = (Node) lowExpr.evaluate(entryNode,
									XPathConstants.NODE);
							if (lowNode != null) {
								try {
									lowString = lowNode.getAttributes()
											.getNamedItem("value")
											.getNodeValue();
									lowString = dateDecorate(lowString);
								} catch (Exception e) {
									log.error("Error parsing low node ...");
								}

							}

							String highString = "";
							Node highNode = (Node) highExpr.evaluate(entryNode,
									XPathConstants.NODE);
							if (highNode != null) {
								try {
									highString = highNode.getAttributes()
											.getNamedItem("value")
											.getNodeValue();
									highString = dateDecorate(highString);
								} catch (Exception e) {
									log.error("Error parsing high node ...");
								}
							}

							Boolean substitutionPermitted = Boolean.TRUE;
							Node substituteNode = (Node) substituteInstrExpr
									.evaluate(entryNode, XPathConstants.NODE);
							if (substituteNode != null) {
								String substituteValue = "";
								try {
									substituteValue = substituteNode
											.getAttributes()
											.getNamedItem("code")
											.getNodeValue();
								} catch (Exception e) {
									substituteValue = "N";
								}
								if (substituteValue.equals("N")) {
									substitutionPermitted = false;
								}
								if (substituteValue.equals("EC")) {
									substitutionPermitted = true;
								}
								if (!substituteValue.equals("N")
										&& !substituteValue.equals("EC")) {
									substitutionPermitted = false;
								}

								// try {
								// substitutionPermitted = new
								// Boolean(substituteValue);
								// } catch (Exception e) {
								// substitutionPermitted=false;
								// }
							}

							line.setField1(name);
							line.setField2(ingredient);
							line.setField3(strength);
							line.setField4(packsString);

							line.setField5(doseString);
							line.setField6(freqString);
							line.setField7(routeString);
							line.setField8(nrOfPacks);

							line.setField9(lowString);
							line.setField10(highString);

							line.setField11(patientString);
							line.setField12(fillerString);

							line.setField13(prescriber);

							// entry header information
							line.setField14(prescriptionID);

							// prescription header information
							line.setField15(performer);
							line.setField16(profession);
							line.setField17(facility);
							line.setField18(address);

							line.setField19(materialID);

							line.setField20(substitutionPermitted);
							line.setField21(dispensedPackage);
							line.setField22(dispensedPackageUnit);
							line.setMainid(lines.size());

							lines.add(line);
						}
					}

				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return lines;
	}

	@SuppressWarnings("deprecation")
	private static void signSAMLAssertion(SignableSAMLObject as,
			String keyAlias, char[] keyPassword) throws Exception {

		ConfigurationManagerService cms = ConfigurationManagerService
				.getInstance();
		String KEYSTORE_LOCATION = cms.getProperty("javax.net.ssl.keyStore");
		String KEY_STORE_PASS = cms
				.getProperty("javax.net.ssl.keyStorePassword"); // GetterUtil.getString(GnPropsUtil.get("portalb",
																// "KEYSTORE_PASSWORD"),"spirit");
		String KEY_ALIAS = cms.getProperty("javax.net.ssl.key.alias"); // GetterUtil.getString(GnPropsUtil.get("portalb",
																		// "PRIVATEKEY_ALIAS"),"server1");
		String PRIVATE_KEY_PASS = cms
				.getProperty("javax.net.ssl.privateKeyPassword"); // GetterUtil.getString(GnPropsUtil.get("portalb",
																	// "PRIVATEKEY_PASSWORD"),"spirit");

		KeyStoreManager keyManager = new DefaultKeyStoreManager();
		// KeyPair kp = null;
		X509Certificate cert = null;
		// check if we must use the default key
		PrivateKey privateKey = null;
		PublicKey publicKey = null;
		if (keyAlias == null) {
			cert = (X509Certificate) keyManager.getDefaultCertificate();
		} else {
			KeyStore keyStore = KeyStore.getInstance("JKS");
			ClassLoader cl = Thread.currentThread().getContextClassLoader();
			File file = new File(KEYSTORE_LOCATION);
			keyStore.load(new FileInputStream(file),
					KEY_STORE_PASS.toCharArray());
			privateKey = (PrivateKey) keyStore.getKey(KEY_ALIAS,
					PRIVATE_KEY_PASS.toCharArray());
			X509Certificate cert1 = (X509Certificate) keyStore
					.getCertificate(KEY_ALIAS);
			publicKey = cert1.getPublicKey();
			cert = (X509Certificate) keyManager.getCertificate(keyAlias);
		}

		org.opensaml.xml.signature.Signature sig = (org.opensaml.xml.signature.Signature) Configuration
				.getBuilderFactory()
				.getBuilder(
						org.opensaml.xml.signature.Signature.DEFAULT_ELEMENT_NAME)
				.buildObject(
						org.opensaml.xml.signature.Signature.DEFAULT_ELEMENT_NAME);
		Credential signingCredential = SecurityHelper.getSimpleCredential(cert,
				privateKey);

		sig.setSigningCredential(signingCredential);
		sig.setSignatureAlgorithm("http://www.w3.org/2000/09/xmldsig#rsa-sha1");
		sig.setCanonicalizationAlgorithm("http://www.w3.org/2001/10/xml-exc-c14n#");

		SecurityConfiguration secConfig = Configuration
				.getGlobalSecurityConfiguration();
		try {
			SecurityHelper.prepareSignatureParams(sig, signingCredential,
					secConfig, null);
		} catch (SecurityException e) {
			throw new SMgrException(e.getMessage(), e);
		}

		as.setSignature(sig);
		try {
			Configuration.getMarshallerFactory().getMarshaller(as).marshall(as);
		} catch (MarshallingException e) {
			throw new SMgrException(e.getMessage(), e);
		}
		try {
			org.opensaml.xml.signature.Signer.signObject(sig);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static Object getUserAssertion() {
		User user = LiferayUtils.getPortalUser();
		Assertion assertion = null;

		try {

			boolean isPhysician = LiferayUtils.isDoctor(user.getUserId(),
					user.getCompanyId());
			boolean isPharmacist = LiferayUtils.isPharmacist(user.getUserId(),
					user.getCompanyId());
			boolean isNurse = LiferayUtils.isNurse(user.getUserId(),
					user.getCompanyId());
			boolean isAdministrator = LiferayUtils.isAdministrator(
					user.getUserId(), user.getCompanyId());

			String orgName = "";

			Vector perms = new Vector();

			String username = user.getScreenName();
			String rolename = "";
			String prefix = "urn:oasis:names:tc:xspa:1.0:subject:hl7:permission:";

			if (isPhysician) {
				rolename = "medical doctor";

				String doctor_perms = GetterUtil
						.getString(com.liferay.util.portlet.PortletProps
								.get("medical.doctor.perms"),
								"PRD-006,PRD-003,PRD-005,PRD-010,PRD-016,PPD-004,PPD-032,PPD-046,POE-006");
				String p[] = doctor_perms.split(",");
				for (int k = 0; k < p.length; k++) {
					perms.add(prefix + p[k]);
				}
			}
			if (isPharmacist) {
				rolename = "pharmacist";
				String pharm_perms = GetterUtil
						.getString(com.liferay.util.portlet.PortletProps
								.get("pharmacist.perms"),
								"PRD-006,PRD-003,PRD-005,PRD-010,PRD-016,PPD-004,PPD-032,PPD-046,POE-006");
				String p1[] = pharm_perms.split(",");
				for (int k = 0; k < p1.length; k++) {
					perms.add(prefix + p1[k]);
				}
			}

			if (isNurse) {
				rolename = "nurse";
				String nurse_perms = GetterUtil.getString(
						com.liferay.util.portlet.PortletProps
								.get("nurse.perms"), "PRD-006,PRD-004,PRD-010");
				String p1[] = nurse_perms.split(",");
				for (int k = 0; k < p1.length; k++) {
					perms.add(prefix + p1[k]);
				}
			}

			if (isAdministrator) {
				rolename = "administrator";
				String admin_perms = GetterUtil
						.getString(com.liferay.util.portlet.PortletProps
								.get("administrator,perms"),
								"PRD-006,PRD-003,PRD-005,PRD-010,PRD-016,PPD-004,PPD-032,PPD-046,POE-006");
				String p1[] = admin_perms.split(",");
				for (int k = 0; k < p1.length; k++) {
					perms.add(prefix + p1[k]);
				}
			}

			orgName = LiferayUtils.getPortalCompany().getName();
			String poc = "POC";
			String orgId = LiferayUtils.getPortalCompany().getCompanyId() + "";
			String orgType = "N/A";

			assertion = EpsosHelperService.createAssertion(username, rolename,
					orgName, orgId, orgType, "TREATMENT", poc, perms);

			if (isPhysician || isPharmacist || isNurse) {

				log.info("Getting config manager");
				ConfigurationManagerService cms = ConfigurationManagerService
						.getInstance();

				String KEY_ALIAS = cms.getProperty("javax.net.ssl.key.alias"); // GetterUtil.getString(GnPropsUtil.get("portalb",
				log.info("KEY ALIAS: " + KEY_ALIAS); // "PRIVATEKEY_ALIAS"),"server1");
				String PRIVATE_KEY_PASS = cms
						.getProperty("javax.net.ssl.privateKeyPassword"); // GetterUtil.getString(GnPropsUtil.get("portalb",
																			// "PRIVATEKEY_PASSWORD"),"spirit");

				signSAMLAssertion(assertion, KEY_ALIAS,
						PRIVATE_KEY_PASS.toCharArray());

				AssertionMarshaller marshaller = new AssertionMarshaller();
				Element element = null;

				element = marshaller.marshall(assertion);

				Document document = element.getOwnerDocument();

			}
			System.out.println("Assertion: " + assertion.getID());
		} catch (Exception e) {
			e.printStackTrace();
			return e.getMessage();
		}

		LiferayUtils.storeToSession("hcpAssertion", assertion);

		return assertion;
	}

	private static Attribute createAttribute(
			XMLObjectBuilderFactory builderFactory, String FriendlyName,
			String oasisName) {
		Attribute attrPID = create(Attribute.class,
				Attribute.DEFAULT_ELEMENT_NAME);
		attrPID.setFriendlyName(FriendlyName);
		attrPID.setName(oasisName);
		attrPID.setNameFormat(Attribute.URI_REFERENCE);
		return attrPID;
	}

	private static Attribute AddAttributeValue(
			XMLObjectBuilderFactory builderFactory, Attribute attribute,
			String value, String namespace, String xmlschema) {
		XMLObjectBuilder stringBuilder = builderFactory
				.getBuilder(XSString.TYPE_NAME);
		XSString attrValPID = (XSString) stringBuilder.buildObject(
				AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME);
		attrValPID.setValue(value);
		attribute.getAttributeValues().add(attrValPID);
		return attribute;
	}

	private static Attribute createAttribute(
			XMLObjectBuilderFactory builderFactory, String FriendlyName,
			String oasisName, String value, String namespace, String xmlschema) {
		Attribute attrPID = create(Attribute.class,
				Attribute.DEFAULT_ELEMENT_NAME);
		attrPID.setFriendlyName(FriendlyName);
		attrPID.setName(oasisName);
		attrPID.setNameFormat(Attribute.URI_REFERENCE);
		// Create and add the Attribute Value

		XMLObjectBuilder stringBuilder = null;

		if (namespace.equals("")) {
			XSString attrValPID = null;
			stringBuilder = builderFactory.getBuilder(XSString.TYPE_NAME);
			attrValPID = (XSString) stringBuilder.buildObject(
					AttributeValue.DEFAULT_ELEMENT_NAME, XSString.TYPE_NAME);
			attrValPID.setValue(value);
			attrPID.getAttributeValues().add(attrValPID);
		} else {
			XSURI attrValPID = null;
			stringBuilder = builderFactory.getBuilder(XSURI.TYPE_NAME);
			attrValPID = (XSURI) stringBuilder.buildObject(
					AttributeValue.DEFAULT_ELEMENT_NAME, XSURI.TYPE_NAME);
			attrValPID.setValue(value);
			attrPID.getAttributeValues().add(attrValPID);
		}

		return attrPID;
	}

	private static <T> T create(Class<T> cls, QName qname) {
		return (T) ((XMLObjectBuilder) Configuration.getBuilderFactory()
				.getBuilder(qname)).buildObject(qname);
	}

	private static Assertion createAssertion(String username, String role,
			String organization, String organizationId, String facilityType,
			String purposeOfUse, String xspaLocality,
			java.util.Vector permissions) {
		// assertion
		Assertion assertion = null;
		try {
			DefaultBootstrap.bootstrap();
			XMLObjectBuilderFactory builderFactory = Configuration
					.getBuilderFactory();

			SAMLObjectBuilder<Assertion> builder = (SAMLObjectBuilder<Assertion>) builderFactory
					.getBuilder(Assertion.DEFAULT_ELEMENT_NAME);

			// Create the NameIdentifier
			SAMLObjectBuilder nameIdBuilder = (SAMLObjectBuilder) builderFactory
					.getBuilder(NameID.DEFAULT_ELEMENT_NAME);
			NameID nameId = (NameID) nameIdBuilder.buildObject();
			nameId.setValue(username);
			// nameId.setNameQualifier(strNameQualifier);
			nameId.setFormat(NameID.UNSPECIFIED);

			assertion = create(Assertion.class, Assertion.DEFAULT_ELEMENT_NAME);

			String assId = "_" + UUID.randomUUID();
			assertion.setID(assId);
			assertion.setVersion(SAMLVersion.VERSION_20);
			assertion.setIssueInstant(new org.joda.time.DateTime()
					.minusHours(3));

			Subject subject = create(Subject.class,
					Subject.DEFAULT_ELEMENT_NAME);
			assertion.setSubject(subject);
			subject.setNameID(nameId);

			// Create and add Subject Confirmation
			SubjectConfirmation subjectConf = create(SubjectConfirmation.class,
					SubjectConfirmation.DEFAULT_ELEMENT_NAME);
			subjectConf.setMethod(SubjectConfirmation.METHOD_SENDER_VOUCHES);
			assertion.getSubject().getSubjectConfirmations().add(subjectConf);

			// Create and add conditions
			Conditions conditions = create(Conditions.class,
					Conditions.DEFAULT_ELEMENT_NAME);
			org.joda.time.DateTime now = new org.joda.time.DateTime();
			conditions.setNotBefore(now.minusMinutes(1));
			conditions.setNotOnOrAfter(now.plusHours(2)); // According to Spec
			assertion.setConditions(conditions);

			// AudienceRestriction ar =
			// create(AudienceRestriction.class,AudienceRestriction.DEFAULT_ELEMENT_NAME);
			// Audience aud =
			// create(Audience.class,Audience.DEFAULT_ELEMENT_NAME);
			// aud.setAudienceURI("aaa");

			// conditions.s

			Issuer issuer = new IssuerBuilder().buildObject();
			issuer.setValue("urn:idp:countryB");
			issuer.setNameQualifier("urn:epsos:wp34:assertions");
			assertion.setIssuer(issuer);

			// Add and create the authentication statement
			AuthnStatement authStmt = create(AuthnStatement.class,
					AuthnStatement.DEFAULT_ELEMENT_NAME);
			authStmt.setAuthnInstant(now.minusHours(2));
			assertion.getAuthnStatements().add(authStmt);

			// Create and add AuthnContext
			AuthnContext ac = create(AuthnContext.class,
					AuthnContext.DEFAULT_ELEMENT_NAME);
			AuthnContextClassRef accr = create(AuthnContextClassRef.class,
					AuthnContextClassRef.DEFAULT_ELEMENT_NAME);
			accr.setAuthnContextClassRef(AuthnContext.PASSWORD_AUTHN_CTX);
			ac.setAuthnContextClassRef(accr);
			authStmt.setAuthnContext(ac);

			AttributeStatement attrStmt = create(AttributeStatement.class,
					AttributeStatement.DEFAULT_ELEMENT_NAME);

			// XSPA Subject
			Attribute attrPID = createAttribute(builderFactory, "XSPA subject",
					"urn:oasis:names:tc:xacml:1.0:subject:subject-id",
					username, "", "");
			attrStmt.getAttributes().add(attrPID);
			// XSPA Role
			Attribute attrPID_1 = createAttribute(builderFactory, "XSPA role",
					"urn:oasis:names:tc:xacml:2.0:subject:role", role, "", "");
			attrStmt.getAttributes().add(attrPID_1);
			// HITSP Clinical Speciality
			/*
			 * Attribute attrPID_2 =
			 * createAttribute(builderFactory,"HITSP Clinical Speciality",
			 * "urn:epsos:names:wp3.4:subject:clinical-speciality",role,"","");
			 * attrStmt.getAttributes().add(attrPID_2);
			 */
			// XSPA Organization
			Attribute attrPID_3 = createAttribute(builderFactory,
					"XSPA Organization",
					"urn:oasis:names:tc:xspa:1.0:subject:organization",
					organization, "", "");
			attrStmt.getAttributes().add(attrPID_3);
			// XSPA Organization ID
			Attribute attrPID_4 = createAttribute(builderFactory,
					"XSPA Organization ID",
					"urn:oasis:names:tc:xspa:1.0:subject:organization-id",
					organizationId, "AA", "");
			attrStmt.getAttributes().add(attrPID_4);

			// // On behalf of
			// Attribute attrPID_4 =
			// createAttribute(builderFactory,"OnBehalfOf",
			// "urn:epsos:names:wp3.4:subject:on-behalf-of",organizationId,role,"");
			// attrStmt.getAttributes().add(attrPID_4);

			// epSOS Healthcare Facility Type
			Attribute attrPID_5 = createAttribute(builderFactory,
					"epSOS Healthcare Facility Type",
					"urn:epsos:names:wp3.4:subject:healthcare-facility-type",
					facilityType, "", "");
			attrStmt.getAttributes().add(attrPID_5);
			// XSPA Purpose of Use
			Attribute attrPID_6 = createAttribute(builderFactory,
					"XSPA Purpose Of Use",
					"urn:oasis:names:tc:xspa:1.0:subject:purposeofuse",
					purposeOfUse, "", "");
			attrStmt.getAttributes().add(attrPID_6);
			// XSPA Locality
			Attribute attrPID_7 = createAttribute(builderFactory,
					"XSPA Locality",
					"urn:oasis:names:tc:xspa:1.0:environment:locality",
					xspaLocality, "", "");
			attrStmt.getAttributes().add(attrPID_7);
			// HL7 Permissions
			Attribute attrPID_8 = createAttribute(builderFactory,
					"Hl7 Permissions",
					"urn:oasis:names:tc:xspa:1.0:subject:hl7:permission");
			Iterator itr = permissions.iterator();
			while (itr.hasNext()) {
				attrPID_8 = AddAttributeValue(builderFactory, attrPID_8, itr
						.next().toString(), "", "");
			}
			attrStmt.getAttributes().add(attrPID_8);

			assertion.getStatements().add(attrStmt);

		} catch (ConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return assertion;
	}

	public static String getCountriesFromCS() {
		System.out.println("get Countries from CS");
		String listOfCountries = "";
		String filename = "InternationalSearch.xml";
		try {
			FacesContext facesContext = FacesContext.getCurrentInstance();
			ExternalContext externalContext = facesContext.getExternalContext();
			String wi = externalContext.getRealPath("/") + "/WEB-INF/";

			String path = wi + "forms" + File.separator + filename;
			File file = new File(path);
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			NodeList nodeLst = doc.getElementsByTagName("country");
			String seperator = "";
			for (int s = 0; s < nodeLst.getLength(); s++) {
				Node fstNode = nodeLst.item(s);
				// if (s>0) {seperator=",";}
				if (listOfCountries.length() > 1) {
					seperator = ",";
				}
				Element link = (Element) nodeLst.item(s);
				String a1 = link.getAttribute("code");
				if (getCountryIdsFromCS(a1).get(0) != null) {
					listOfCountries = listOfCountries + seperator + a1;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return listOfCountries;
	}

	public static List<Country> getCountriesFromCS(String lang) {
		System.out.println("get Countries from CS with lang");
		List<Country> listOfCountries = new ArrayList<Country>();
		String filename = "InternationalSearch.xml";
		try {
			FacesContext facesContext = FacesContext.getCurrentInstance();
			ExternalContext externalContext = facesContext.getExternalContext();
			String wi = externalContext.getRealPath("/") + "/WEB-INF/";
			String path = wi + "forms" + File.separator + filename;

			File file = new File(path);
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			NodeList nodeLst = doc.getElementsByTagName("country");
			String seperator = "";
			for (int s = 0; s < nodeLst.getLength(); s++) {
				Node fstNode = nodeLst.item(s);
				Element link = (Element) nodeLst.item(s);
				String a1 = link.getAttribute("code");
				// if (getCountryIdsFromCS(a1).get(0) != null) {
				// listOfCountries = listOfCountries + seperator + a1;
				// }
				// get country name for the specific user selected lang
				// String countryName=getCountryNameFromCS(lang, a1);
				Country country = new Country("", a1);
				listOfCountries.add(country);
			}
			getCountryListNameFromCS(lang, listOfCountries);

		} catch (Exception e) {
			System.out.println("getCountriesFromCS: " + e.getMessage());
		}
		return listOfCountries;
	}

	private static String getCountryNameFromCS(String lang, String countryCode) {
		System.out.println("get Country names from CS for " + countryCode);
		try {
			FacesContext facesContext = FacesContext.getCurrentInstance();
			ExternalContext externalContext = facesContext.getExternalContext();
			String wi = externalContext.getRealPath("/") + "/WEB-INF/";
			String path = wi + "language" + File.separator + "application"
					+ File.separator + lang + File.separator
					+ "SpiritEhrPortal.xml";
			File file = new File(path);
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			XPath xpath = XPathFactory.newInstance().newXPath();
			String translation = xpath.evaluate("//*[@key='" + countryCode
					+ "']", doc);
			return translation;
		} catch (Exception ex) {
			System.out.println("getCountriesNamesFromCS: " + ex.getMessage());
			return "";
		}

	}

	public static void getCountryListNameFromCS(String lang,
			List<Country> countriesList) {

		try {
			FacesContext facesContext = FacesContext.getCurrentInstance();
			ExternalContext externalContext = facesContext.getExternalContext();
			String wi = externalContext.getRealPath("/") + "/WEB-INF/";
			String path = wi + "language" + File.separator + "application"
					+ File.separator + lang + File.separator
					+ "SpiritEhrPortal.xml";
			File file = new File(path);
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();

			for (int i = 0; i < countriesList.size(); i++) {
				Country country = countriesList.get(i);
				String translation = country.getCode();

				XPath xpath = XPathFactory.newInstance().newXPath();
				translation = xpath.evaluate("//*[@key='" + country.getCode()
						+ "']", doc);
				if (Validator.isNull(translation))
					translation = country.getCode();
				country.setName(translation);
			}
		} catch (Exception ex) {
			System.out.println("getCountriesNamesFromCS: " + ex.getMessage());
		}

	}

	public static String getCountriesLabelsFromCS(String language) {
		System.out.println("get Countries labels from CS");
		String listOfCountries = "";

		String filename = "InternationalSearch.xml";
		try {
			FacesContext facesContext = FacesContext.getCurrentInstance();
			ExternalContext externalContext = facesContext.getExternalContext();
			String wi = externalContext.getRealPath("/") + "/WEB-INF/";
			// String path = cl.getResource(".").getPath();
			// System.out.println("#### 1: " + a1);
			String path = wi + "forms" + File.separator + filename;
			File file = new File(path);
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			NodeList nodeLst = doc.getElementsByTagName("country");
			String seperator = "";
			for (int s = 0; s < nodeLst.getLength(); s++) {
				Node fstNode = nodeLst.item(s);
				if (listOfCountries.length() > 1) {
					seperator = ",";
				}
				Element link = (Element) nodeLst.item(s);
				String a1 = EpsosHelperService.getPortalTranslation(
						link.getAttribute("code"), language);
				Vector v = getCountryIdsFromCS(link.getAttribute("code"));
				SearchMask sm = (SearchMask) v.get(0);
				if (sm.getDomain() != null) {
					listOfCountries = listOfCountries + seperator + a1;
				}

			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return listOfCountries;
	}

	public static Vector getCountryIdsFromCS(String country) {
		Vector v = new Vector();

		String filename = "InternationalSearch_" + country + ".xml";
		try {
			FacesContext facesContext = FacesContext.getCurrentInstance();
			ExternalContext externalContext = facesContext.getExternalContext();
			String wi = externalContext.getRealPath("/") + "/WEB-INF/";

			// ClassLoader cl = Thread.currentThread().getContextClassLoader();
			// String path = cl.getResource(".").getPath();

			String path = wi + "forms" + File.separator + filename;

			File file = new File(path);

			// File file = new File(internationalSearchPath+filename);
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			// ids
			NodeList nodeLst = doc.getElementsByTagName("id");
			// attrs[0]="";
			for (int s = 0; s < nodeLst.getLength(); s++) {
				Node fstNode = nodeLst.item(s);
				Element link = (Element) nodeLst.item(s);
				SearchMask sm = new SearchMask();
				sm.setDomain(link.getAttribute("domain"));
				sm.setLabel(link.getAttribute("label"));
				v.add(sm);
				// attrs[0] = attrs[0] + seperator + a1;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return v;
	}

	public static Vector getCountryDemographicsFromCS(String country) {
		Vector v = new Vector();

		String filename = "InternationalSearch_" + country + ".xml";
		try {
			FacesContext facesContext = FacesContext.getCurrentInstance();
			ExternalContext externalContext = facesContext.getExternalContext();
			String wi = externalContext.getRealPath("/") + "/WEB-INF/";

			// ClassLoader cl = Thread.currentThread().getContextClassLoader();
			// String path = cl.getResource(".").getPath();

			String path = wi + "forms" + File.separator + filename;

			File file = new File(path);

			// File file = new File(internationalSearchPath+filename);
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			// textFields
			NodeList nodeLst = doc.getElementsByTagName("textField");
			for (int s = 0; s < nodeLst.getLength(); s++) {
				Node fstNode = nodeLst.item(s);
				Element link = (Element) nodeLst.item(s);
				Demographics dem = new Demographics();
				dem.setLabel(link.getAttribute("label"));
				dem.setKey(link.getAttribute("label"));
				dem.setLength(Integer.parseInt(link.getAttribute("min")));
				// search for mandatory items
				NodeList nodeLst2 = doc.getElementsByTagName("field");
				for (int i = 0; i < nodeLst2.getLength(); i++) {
					Node fstNode2 = nodeLst2.item(i);
					Element link2 = (Element) nodeLst2.item(i);
					if (link2.getAttribute("label").equals(dem.getLabel())) {
						dem.setMandatory(true);
						break;
					}
				}
				v.add(dem);
			}
			// sex
			 nodeLst = doc.getElementsByTagName("sex");
			for (int s = 0; s < nodeLst.getLength(); s++) {
				Node fstNode = nodeLst.item(s);
				Element link = (Element) nodeLst.item(s);
				Demographics dem = new Demographics();
				dem.setLabel(link.getAttribute("label"));
				dem.setKey(link.getAttribute("label"));
				
				v.add(dem);
			}	
			// birth date
			 nodeLst = doc.getElementsByTagName("birthDate");
			for (int s = 0; s < nodeLst.getLength(); s++) {				
				Node fstNode = nodeLst.item(s);
				Element link = (Element) nodeLst.item(s);				
				Demographics dem = new Demographics();
				dem.setLabel(link.getAttribute("label"));
				dem.setKey(link.getAttribute("label"));

				v.add(dem);
			}	
		} catch (Exception e) {
			e.printStackTrace();
		}
		return v;
	}

	public static String getPortalTranslation(String key, String language) {

		String translation = "";
		language = language.replaceAll("_", "-");
		try {

			FacesContext facesContext = FacesContext.getCurrentInstance();
			ExternalContext externalContext = facesContext.getExternalContext();
			String wi = externalContext.getRealPath("/") + "/WEB-INF/";

			// ClassLoader cl = Thread.currentThread().getContextClassLoader();
			// String path = cl.getResource(".").getPath();
			String path = wi + "language" + File.separator + "application"
					+ File.separator + language + File.separator
					+ "SpiritEhrPortal.xml";
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			dbf.setValidating(false);
			dbf.setFeature(
					"http://apache.org/xml/features/nonvalidating/load-external-dtd",
					false);
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(path);
			doc.getDocumentElement().normalize();
			XPath xpath = XPathFactory.newInstance().newXPath();
			translation = xpath.evaluate("//*[@key='" + key + "']", doc);
			// if (Validator.isNull(translation)) translation = key;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return translation;
	}

	public static Assertion createPatientConfirmationPlain(String purpose,
			Assertion idAs, PatientId patient) throws PortalException,
			SystemException {
		Assertion trc = null;
		Document document = null;
		Document signedDoc = null;
		log.info("Try to create TRCA for patient : " + patient.getExtension());
		try {
			// netsmart assertion
			String pat = "";
			try {
				pat = patient.getExtension() + "^^^&" + patient.getRoot()
						+ "&ISO";
				log.info("TRCA Patient ID : " + pat);
				TRCAssertionRequest req1 = new TRCAssertionRequest.Builder(
						idAs, pat).PurposeOfUse(purpose).build();
				trc = req1.request();
				log.info("TRCA CREATED: " + trc.getID());
				log.info("TRCA WILL BE STORED TO SESSION: " + trc.getID());
				LiferayUtils.storeToSession("trcAssertion", trc);
			} catch (Exception e) {
				log.error("TRCA CREATION ERROR : " + e.getMessage());
				e.printStackTrace();
			}

		} catch (Exception e2) {
			e2.printStackTrace();
		}
		return trc;
	}

	public static byte[] extractPdfPartOfDocument(byte[] bytes) {
		byte[] result = bytes;

		try {
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document dom = db.parse(new ByteArrayInputStream(bytes));

			XPath xpath = XPathFactory.newInstance().newXPath();
			XPathExpression pdfTag = xpath
					.compile("//component/nonXMLBody/text[@mediaType='application/pdf']");
			Node pdfNode = (Node) pdfTag.evaluate(dom, XPathConstants.NODE);
			if (pdfNode != null) {
				String base64EncodedPdfString = pdfNode.getTextContent().trim();
				result = decode.decode(base64EncodedPdfString.getBytes());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;
	}

	public static String getSafeString(String arg0) {
		String result = "";
		try {
			if (Validator.isNull(arg0)) {
				log.error("Error getting safe string. USING N/A");
				result = "N/A";
			} else {
				result = arg0;
			}
		} catch (Exception e) {
			log.error("Error getting safe string");
		}
		return result;
	}

	public static void changeNode(Document dom, XPath xpath, String path,
			String nodeName, String value) {
		try {
			XPathExpression salRO = xpath.compile(path + "/" + nodeName);
			NodeList salRONodes = (NodeList) salRO.evaluate(dom,
					XPathConstants.NODESET);
			if (salRONodes.getLength() > 0) {
				for (int t = 0; t < salRONodes.getLength(); t++) {
					Node AddrNode = salRONodes.item(t);
					if (AddrNode.getNodeName().equals("name")) {
						AddrNode.setTextContent(value);
					}
				}
			}
		} catch (Exception e) {
			log.error("Error fixing node ...");
		}
	}

	/**
	 * Create an attribute node of the form attributeName="attributeValue" and
	 * add it to node
	 * 
	 * @param dom
	 * @param node
	 * @param attributeName
	 * @param attributeValue
	 */
	public static void addAttribute(Document dom, Node node,
			String attributeName, String attributeValue) {
		Attr rootAttr = dom.createAttribute(attributeName);
		rootAttr.setValue(attributeValue);
		node.getAttributes().setNamedItem(rootAttr);
	}

	public static String formatDateHL7(Date date) {
		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
		String s = formatter.format(date);
		return s;
	}

	private static String dateDecorate(String input) {
		String result = input;
		if (input != null) {
			try {
				String year = input.substring(0, 4);
				String month = input.substring(4, 6);
				String day = input.substring(6);
				result = day + "/" + month + "/" + year;
			} catch (Exception e) {
			}
		}
		return result;
	}

}
